package homework.course.role;

import homework.course.Message;
import homework.course.MessageType;
import homework.course.role.state.*;
import homework.util.observer.Observable;

import java.util.HashMap;
import java.util.Map;

public class Student extends Animal implements Classable {

    private static Map<String, Student> stdInstances = new HashMap<String, Student>();

    private StudentState concentrateState;
    private StudentState distractedState;
    private StudentState sleepState;
    private StudentState playingState;
    private StudentState currentState;

    private String name;
    private String sno;

    private Student(String no, String name) {
        this.sno = no;
        this.name = name;

        concentrateState = new ConcentrateState(this);
        sleepState = new SleepState(this);
        distractedState = new DistractedState(this);
        playingState = new PlayingState(this);
        currentState = concentrateState;

        stdInstances.put(no, this);
    }

    public StudentState getConcentrateState() {
        return concentrateState;
    }

    public StudentState getSleepState() {
        return sleepState;
    }

    public StudentState getDistractedState() {
        return distractedState;
    }

    public StudentState getPlayingState() {
        return playingState;
    }

    public StudentState getCurrentState() {
        return currentState;
    }

    public void setState(StudentState state) {
        if(state != currentState) {
            currentState = state;
            notifyObservers(new Message(state.getInformation(), MessageType.SYSTEM));
        }
    }

    public String getNO() {
        return sno;
    }

    public String getName() {
        return name;
    }

    public void wakeUp() {
        notifyObservers(new Message("被叫醒了", MessageType.SYSTEM));
        setState(concentrateState);
    }

    @Override
    public String speak() {
        String msg = currentState.speak();
        setState(concentrateState);
        return msg;
    }

    @Override
    public void listen(Object obj, String msg) {
        if(obj != this)
            currentState.listen(obj, msg);
    }

    @Override
    public void receive(Observable observable, Object obj) {
        listen(observable, obj.toString());
    }

    @Override
    public String toString() {
        return sno+name;
    }

    public static Student getInstance(String sno, String name) {
        Student std = stdInstances.get(sno);
        if(std == null) {
            std = new Student(sno, name);
        } else if (!std.getName().equals(name)) {
            throw new IllegalArgumentException(std+"姓名不为"+name);
        }
        return std;
    }
}
